package com.itzzy.dice.codec;

import cn.hutool.core.util.ReflectUtil;
import com.itzzy.dice.constant.RequestCode;
import io.netty.buffer.ByteBuf;
import lombok.SneakyThrows;
import xyz.noark.core.lang.ByteArray;
import xyz.noark.core.lang.ByteArrayOutputStream;
import xyz.noark.core.lang.ImmutableByteArray;
import xyz.noark.core.network.NetworkPacket;
import xyz.noark.core.network.NetworkProtocol;
import xyz.noark.network.codec.AbstractWebsocketPacketCodec;
import xyz.noark.network.codec.ByteBufWrapper;
import xyz.noark.network.codec.DefaultNetworkPacket;

import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;

/**
 * @author zzy
 * @version 1.0
 * @date 2021/3/23 14:13
 */
public class DiceMessageCodec extends AbstractWebsocketPacketCodec {

    @Override
    public NetworkPacket decodePacket(ByteBuf byteBuf) {
        DefaultNetworkPacket packet = new DefaultNetworkPacket();
        //设置封包长度
        packet.setLength(byteBuf.readableBytes() - RequestCode.PACKAGE_LENGTH);
        //获取请求的信息
        byte[] strByte = new byte[RequestCode.PACKAGE_LENGTH];
        byteBuf.readBytes(strByte);
        String msg = new String(strByte, StandardCharsets.UTF_8);
        try {
            if (msg.contains("|")) {
                String[] split = msg.split("\\|");
                packet.setOpcode(Integer.parseInt(split[0]));
                packet.setBytes(new ByteBufWrapper(byteBuf));
                return packet;
            }
            return null;
        }catch (Exception e) {
            return null;
        }
    }

    @SneakyThrows
    @Override
    public <T> T decodeProtocol(ByteArray bytes, Class<T> klass) {
        String result = new String(bytes.array(), StandardCharsets.UTF_8).trim();
        if (klass.isAssignableFrom(String.class)){
            return klass.cast(result);
        }else {
            String[] split = result.split("\\|");
            T t = klass.newInstance();
            Field[] fields = ReflectUtil.getFields(klass);
            for (int i = 0; i < fields.length; i++) {
                ReflectUtil.setFieldValue(t, fields[i], split[i]);
            }
            return t;
        }
    }

    @Override
    public ByteArray encodePacket(NetworkProtocol protocol) {
        final byte[] bytes = protocol.getProtocol().toString().getBytes(StandardCharsets.UTF_8);
        ImmutableByteArray byteArray = new ImmutableByteArray(bytes.length);
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(byteArray)) {
            // 写入Opcode
//            byteArrayOutputStream.writeInt();
            // 写入协议内容
            byteArrayOutputStream.writeBytes(bytes);
        }
        return byteArray;
    }

}
